﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Client.TopLevel;

namespace PersApp
{
    public partial class EmployeesForm : Form
    {
        private const int SELECT_USER_COLUMN_ID = -1;
        private const int NAME_COLUMN_ID = 0;
        private const int LOGIN_COLUMN_ID = 1;
        private const int PASSWORD_COLUMN_ID = 2;
        private const int POSITION_COLUMN_ID = 3;
        private const int BANK_ACCOUNT_COLUMN_ID = 4;
        private const int ROLE_COLUMN_ID = 5;

        private IManagerEmployee mManager;

        private List<TLPosition> mPositions;

        public EmployeesForm(IManagerEmployee manager)
        {
            InitializeComponent();

            mManager = manager;

            initTable();
            roleComboBox.DataSource = Roles.getRoles();
        }

        private void initTable()
        {
            employeesGridView.Columns.Add("name", "Имя");
            employeesGridView.Columns.Add("login", "Логин");
            employeesGridView.Columns.Add("password", "Пароль");
            employeesGridView.Columns.Add("position", "Должность");
            employeesGridView.Columns.Add("bank_account", "Номер счета");
            employeesGridView.Columns.Add("role", "Полномочия");

            foreach (DataGridViewColumn column in employeesGridView.Columns)
            {
                column.SortMode = DataGridViewColumnSortMode.NotSortable;
                column.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            }

            refreshList();
        }

        private void refreshList()
        {
            employeesGridView.Rows.Clear();

            refreshPositions();

            IEnumerable<TLEmployee> employees = mManager.GetAllEmployees();
            foreach (TLEmployee employee in employees)
            {
                TLPosition position = getPositionByIndex(employee.PositionId);
                Role role = Roles.getRoleByIndex(employee.Role);

                if (position != null && role != null)
                {
                    int rowIndex = employeesGridView.Rows.Add(
                    employee.Name,
                    employee.Login,
                    employee.Password,
                    position,
                    employee.BankAccountId,
                    role);

                    employeesGridView.Rows[rowIndex].Tag = employee;
                }
            }
        }

        private void refreshPositions()
        {
            IEnumerable<TLPosition> positions = mManager.GetAllPositions();
            mPositions = new List<TLPosition>(positions);

            positionComboBox.DataSource = mPositions;
        }

        private List<TLPosition> getPositions()
        {
            return mPositions;
        }

        private TLPosition getPositionByIndex(int index)
        {
            TLPosition position = null;

            foreach(TLPosition p in getPositions())
            {
                if(p.Id == index)
                {
                    position = p;
                    break;
                }
            }

            return position;
        }

        private void employeesGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            switch(e.ColumnIndex)
            {
                case POSITION_COLUMN_ID:
                case ROLE_COLUMN_ID:
                    e.Cancel = true;
                    return;
            }

            if (isAdminRow(e.RowIndex))
            {
                e.Cancel = true;
            }
        }

        private void employeesGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
            {
                return;
            }

            /*if (isAdminRow(e.RowIndex))
            {
                return;
            }*/

            switch (e.ColumnIndex)
            {
                case POSITION_COLUMN_ID:
                    {
                        List<TLPosition> positionsList = getPositions();

                        TLPosition position = (TLPosition)employeesGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                        int select = positionsList.IndexOf(position);

                        ListForm positionSelecter = new ListForm(positionsList, select);
                        positionSelecter.Text = "Выберите должность";

                        if (positionSelecter.ShowDialog() == DialogResult.OK)
                        {
                            TLEmployee employee = (TLEmployee)employeesGridView.Rows[e.RowIndex].Tag;

                            position = (TLPosition)positionSelecter.getSelected();
                            employee.PositionId = position.Id;

                            mManager.EditEmployee(employee, employee);
                            refreshList();
                        }
                    }
                    break;

                case ROLE_COLUMN_ID:
                    {
                        List<Role> rolesList = Roles.getRoles();

                        Role role = (Role)employeesGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                        int select = rolesList.IndexOf(role);

                        ListForm roles = new ListForm(rolesList, select);
                        roles.Text = "Выберите полномочия";

                        if (roles.ShowDialog() == DialogResult.OK)
                        {
                            role = (Role)roles.getSelected();
                            TLEmployee employee = (TLEmployee)employeesGridView.Rows[e.RowIndex].Tag;

                            employee.Role = role.getId();
                            mManager.EditEmployee(employee, employee);

                            refreshList();
                        }
                    }
                    break;

                case SELECT_USER_COLUMN_ID:
                    {
                        TLEmployee employee = (TLEmployee)employeesGridView.Rows[e.RowIndex].Tag;
                        nameTextBox.Text = employee.Name;
                        loginTextBox.Text = employee.Login;
                        passwordTextBox.Text = employee.Password;
                        positionComboBox.SelectedIndex = FindPositionIndex(employee.PositionId);
                        bankAccountTextBox.Text = employee.BankAccountId.ToString();
                        if (employee.Role == TLEmployee.ROLE_MANAGER)
                            roleComboBox.SelectedIndex = 1;
                        else roleComboBox.SelectedIndex = 0;
                    }
                    break;
            }
        }

        private void employeesGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            bool result = false;

            object valueObject = employeesGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
            if (valueObject != null)
            {
                string value = valueObject.ToString();
                bool isValueValid = true;

                TLEmployee employee = (TLEmployee)employeesGridView.Rows[e.RowIndex].Tag;

                switch (e.ColumnIndex)
                {
                    case NAME_COLUMN_ID:
                        employee.Name = value;
                        break;

                    case LOGIN_COLUMN_ID:
                        employee.Login = value;
                        break;

                    case PASSWORD_COLUMN_ID:
                        employee.Password = value;
                        break;

                    case BANK_ACCOUNT_COLUMN_ID:
                        try
                        {
                            employee.BankAccountId = Convert.ToInt32(value);
                        }
                        catch (Exception exception)
                        {
                            System.Console.WriteLine(exception.Message);
                            System.Console.WriteLine(exception.StackTrace);

                            isValueValid = false;
                        }
                        break;
                }

                if (isValueValid)
                {
                    result = mManager.EditEmployee(employee, employee);
                }
            }

            if (result == false)
            {
                MessageBox.Show("Неправильное значение поля.");
            }

            refreshList();
        }

        private void employeesGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            if (isAdminRow(e.Row.Index))
            {
                e.Cancel = true;
                return;
            }

            TLEmployee employee = (TLEmployee)e.Row.Tag;
            bool result = mManager.DeleteEmployee(employee);
            System.Console.WriteLine(String.Concat("Row deletion: ", (result ? "OK" : "failed")));
        }

        private bool isAdminRow(int rowIndex)
        {
            if (String.IsNullOrEmpty(BuildConfig.ADMIN_LOGIN) == false)
            {
                TLEmployee employee = (TLEmployee)employeesGridView.Rows[rowIndex].Tag;
                if (employee.Login.Equals(BuildConfig.ADMIN_LOGIN))
                {
                    return true;
                }
            }

            return false;
        }

        private void addNewEmployeeButton_Click(object sender, EventArgs e)
        {
            bool valuesValid = true;

            TLEmployee employee = new TLEmployee();
            employee.Name = nameTextBox.Text;
            employee.Login = loginTextBox.Text;
            employee.Password = passwordTextBox.Text;

            if (String.IsNullOrEmpty(employee.Name) ||
                String.IsNullOrEmpty(employee.Login) ||
                String.IsNullOrEmpty(employee.Password))
            {
                valuesValid = false;
            }

            try
            {
                employee.BankAccountId = Convert.ToInt32(bankAccountTextBox.Text);
            }
            catch(Exception exception)
            {
                Console.WriteLine(exception.Message);
                Console.WriteLine(exception.StackTrace);

                valuesValid = false;
            }

            employee.PositionId = mPositions[positionComboBox.SelectedIndex].Id;
            employee.Role = Roles.getRoles()[roleComboBox.SelectedIndex].getId();

            bool result = false;
            if (valuesValid)
            {
                result = mManager.AddEmployee(employee);
            }

            if (result)
            {
                refreshList();

                nameTextBox.Text = null;
                loginTextBox.Text = null;
                passwordTextBox.Text = null;
                bankAccountTextBox.Text = null;
            }
            else
            {
                MessageBox.Show("Неправильное значение поля.");
            }
        }

        private void deleteEmployeeButton_Click(object sender, EventArgs e)
        {
            bool valuesValid = true;

            TLEmployee employee = new TLEmployee();
            employee.Name = nameTextBox.Text;
            employee.Login = loginTextBox.Text;
            employee.Password = passwordTextBox.Text;

            if (String.IsNullOrEmpty(employee.Name) ||
                String.IsNullOrEmpty(employee.Login) ||
                String.IsNullOrEmpty(employee.Password))
            {
                valuesValid = false;
            }

            try
            {
                employee.BankAccountId = Convert.ToInt32(bankAccountTextBox.Text);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
                Console.WriteLine(exception.StackTrace);

                valuesValid = false;
            }

            employee.PositionId = mPositions[positionComboBox.SelectedIndex].Id;
            employee.Role = Roles.getRoles()[roleComboBox.SelectedIndex].getId();

            bool result = false;
            if (valuesValid)
            {
                result = mManager.DeleteEmployee(employee);
            }

            if (result)
            {
                refreshList();

                nameTextBox.Text = null;
                loginTextBox.Text = null;
                passwordTextBox.Text = null;
                bankAccountTextBox.Text = null;
            }
            else
            {
                MessageBox.Show("Пользователя не удалось удалить.");
            }
        }

        int FindPositionIndex(int positionId)
        {
            for (int i = 0; i < mPositions.Count; i++)
            {
                if (((TLPosition)mPositions[i]).Id == positionId)
                    return i;
            }
            return -1;
        }
    }
}
